#include "preHeader.h"
#include "PlayBossHook.h"
#include "MapInstance.h"
#include "Session/PacketDispatcher.h"

PlayBossHook::PlayBossHook(MapInstance* pMapInstance)
: IMapHook(pMapInstance)
{
}

PlayBossHook::~PlayBossHook()
{
}

void PlayBossHook::InitLuaEnv()
{
	IMapHook::InitLuaEnv();

	auto L = m_pMapInstance->L;
	lua::class_add<PlayBossHook>(L, "PlayBossHook");
	lua::class_inh<PlayBossHook, IMapHook>(L);
	lua::class_def<PlayBossHook>(L, "SendPacket2Master", &PlayBossHook::SendPacket2Master);

	lua::set(L, "PBST_SyncMember", PBST_SyncMember);
	lua::set(L, "PBST_SyncBoss", PBST_SyncBoss);

	static const std::string scriptFile = "scripts/Hook/PlayBoss.lua";
	RunScriptFile(L, scriptFile, m_pMapInstance, this);
}

void PlayBossHook::InitArgs(const std::string_view& args)
{
	ConstNetBuffer buffer(args.data(), args.size());
	auto startTime = buffer.Read<uint64>();
	auto actvtTime = buffer.Read<uint32>();

	auto t = m_variables.Get<LuaTable>();
	auto funcDeployBoss = t.get<LuaFunc>("DeployBoss");
	while (buffer.IsReadableEmpty()) {
		uint32 spawnId, level;
		uint64 lossHPVal;
		buffer >> spawnId >> level >> lossHPVal;
		auto pSpawn = GetDBEntry<CreatureSpawn>(spawnId);
		vector3f1f pos{pSpawn->x, pSpawn->y, pSpawn->z, pSpawn->o};
		CreatureSpawnArgs args = NewCreatureSpawnArgs(pSpawn, level);
		funcDeployBoss.Call<void>(pSpawn->entry, &pos, &args, lossHPVal);
	}

	auto funcPlay = t.get<LuaFunc>("Play");
	funcPlay.Call<void>(startTime, actvtTime);
}

void PlayBossHook::SendPacket2Master(uint32 opcode, const std::string_view& data) const
{
	sPacketDispatcher.SendPacket2CrossServer(opcode, data);
}

CreatureSpawnArgs PlayBossHook::NewCreatureSpawnArgs(const CreatureSpawn* pSpawn, uint32 level)
{
	CreatureSpawnArgs args;
	args.spawnId = pSpawn->spawnId;
	args.level = level;
	return args;
}
